package com.qf.service.impl;

import com.qf.pojo.Order;
import com.qf.service.OrderService;
import com.qf.service.UserService;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {

    /*
        远程注入，导包时注意导入的是apache的包
        ① 会将这个消费者也注册到zookeeper，同时会将这个接口对应的提供者下信息进行订阅获取zookeeper中这个提供者的信息 -- url
            解析这个url，并且在当前应用的容器中生成一个代理对象，代理对象内部会基于解析到的url中相关的协议、ip、端口和接口的方法信息发起远程调用.
        ② 将上述生成的代理对象添加到当前应用的容器中。后续我们可以使用Autowired实现对象的注入。
     */
    /*
        默认配置，默认超时时间为1s，重试为2次
        注意：当发起重试后，我们原来的调用业务会继续向下执行，而不会结束
            假设这个被重试的业务是一个【非幂等性】的操作，那么就会有问题。

            幂等性：多次操作结果一样， 我们称之为幂等。比如查询
            非幂等性：多次操作结果不一样，我们称之为非幂等。比如新增
                删除-幂等
                更新
                    update xx set money=money-100 where xx=1; -- 非幂等
                    update xx set money=100 where xx=1; -- 幂等


        loadbalance: 负载均衡
            random - 随机，默认值
            ***roundrobin - 轮询，会根据权重值的大小实现权重轮询
            leastactive - 最小活跃数，目前最空闲的机器最优先给其处理,能者多劳
            consistenthash - 一致性hash，参数不变，访问目标机器不变


       cluster: 集群容错
            Failover -- 失败了，重试集群中其他的机器，对于幂等性操作，选择使用
            Failfast -- 失败了，报错返回，不进行重试，对于非幂等性操作，选择使用
            Failsafe
            Failback
            Forking
            Broadcast
     */
//    @Reference(timeout = 1000,retries = 0,version = "1.0",loadbalance = "consistenthash",parameters = {"k1","v1"})
    @Reference(timeout = 1000,
            retries = 2,
            version = "1.0",
            cluster = "failfast",
            stub = "com.qf.stub.OrderServiceStub",
            mock = "com.qf.mock.OrderServiceMock"
    )
    OrderService orderService;

    @Override
    public List<Order> findById(Integer uid) throws InterruptedException {
        System.out.println("通过远程调用查询用户订单");
        return orderService.findByUid(uid);
    }

    public List<Order> findById2(Integer uid) throws InterruptedException {

        System.out.println("通过远程调用查询用户订单");
        return orderService.findByUid(uid);
    }

    public List<Order> findById3(Integer uid) throws InterruptedException {

        System.out.println("通过远程调用查询用户订单");
        return orderService.findByUid(uid);
    }
}
